﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Net.Mail;
using System.Net;
using System.Configuration;
using System.Net.Mime;

namespace AteneoLibri.Utility.Mail
{
    public class MailSender
    {
        /// <summary>
        /// Restituisce un oggetto SmtpClient per l'invio della mail.
        /// </summary>
        /// <param name="mailSetting">Oggetto contenente i settings per l'invio della mail.</param>
        /// <returns></returns>
        private SmtpClient _setSmtpServer(MailSettings mailSetting)
        {
            SmtpClient Smtp = new SmtpClient(mailSetting.SmtpServer);
            if (!string.IsNullOrEmpty(mailSetting.SmtpPort))
                Smtp.Port = int.Parse(mailSetting.SmtpPort);
            Smtp.DeliveryMethod = SmtpDeliveryMethod.Network;
            if (!string.IsNullOrEmpty(mailSetting.UserName) && !string.IsNullOrEmpty(mailSetting.Password))
            {
                Smtp.UseDefaultCredentials = false;
                NetworkCredential NetCredential = new NetworkCredential(mailSetting.UserName, mailSetting.Password);
                Smtp.Credentials = NetCredential;
            }
            else
                Smtp.UseDefaultCredentials = true;
            return Smtp;
        }

        /// <summary>
        /// Invia una mail.
        /// </summary>
        /// <param name="mailTo">Indirizzo del destinatario.</param>
        /// <param name="mailTitle">Titolo della mail.</param>
        /// <param name="mailBody">Corpo della mail.</param>
        /// <param name="isBodyHtml">True se il corpo della mail è HTML.</param>
        public void SendMail(string mailTo, string mailTitle, string mailBody, bool isBodyHtml)
        {
            MailSettings mailSetting = MailSettings.Create();
            using (MailMessage Msg = new MailMessage())
            {
                Msg.From = new MailAddress(mailSetting.MailSender, mailSetting.SenderDisplayName);
                Msg.To.Add(new MailAddress(mailTo));
                Msg.Subject = mailTitle;
                Msg.Body = mailBody;
                Msg.IsBodyHtml = isBodyHtml;
                SmtpClient Smtp = this._setSmtpServer(mailSetting);
                Smtp.Send(Msg);
            }
        }

        /// <summary>
        /// Invia una mail ad una lista di destinatari.
        /// </summary>
        /// <param name="mailTo">Lista contentente gli indirizzi dei destinatari.</param>
        /// <param name="mailTitle">Titolo della mail.</param>
        /// <param name="mailBody">Corpo della mail.</param>
        /// <param name="isBodyHtml">True se il corpo della mail è HTML.</param>
        public void SendMail(List<string> mailTo, string mailTitle, string mailBody, bool isBodyHtml)
        {
            MailSettings mailSetting = MailSettings.Create();
            MailMessage Msg = new MailMessage();
            Msg.From = new MailAddress(mailSetting.MailSender, mailSetting.SenderDisplayName);

            foreach (string item in mailTo)
                Msg.To.Add(new MailAddress(item));

            Msg.Subject = mailTitle;
            Msg.Body = mailBody;
            Msg.IsBodyHtml = isBodyHtml;
            SmtpClient Smtp = this._setSmtpServer(mailSetting);
            Smtp.Send(Msg);
        }

        /// <summary>
        /// Richiama SendMailBCC per l'invio di mail multiple passandogli la lista degli utenti già splittata
        /// </summary>
        /// <param name="list"></param>
        /// <param name="mailTitle"></param>
        /// <param name="mailBody"></param>
        /// <param name="isBodyHtml"></param>
        public void SendBulkMail(List<string> list, string mailTitle, string mailBody, bool isBodyHtml)
        {
            int numOfBulkEmail = Convert.ToInt32(ConfigurationManager.AppSettings["NUM_BULK_EMAIL"].ToString());
            List<IEnumerable<string>> splittedList = SplitEmailList(list, numOfBulkEmail);
            foreach (IEnumerable<string> item in splittedList)
            {
                SendMailBCC(item, mailTitle, mailBody, true);
            }
        }

        /// <summary>
        /// Invia una mail ad una lista di destinatari ed invia una copia della mail a comunicazioni@ateneolibri.it
        /// </summary>
        /// <param name="mailTo">Lista contentente gli indirizzi dei destinatari.</param>
        /// <param name="mailTitle">Titolo della mail.</param>
        /// <param name="mailBody">Corpo della mail.</param>
        /// <param name="isBodyHtml">True se il corpo della mail è HTML.</param>
        public void SendMailBCC(IEnumerable<string> mailTo, string mailTitle, string mailBody, bool isBodyHtml)
        {
            string account = ConfigurationManager.AppSettings["MAIL_ComunicationSender"].ToString();
            string password = ConfigurationManager.AppSettings["MAIL_ComunicationPassword"].ToString();

            try
            {
                MailSettings mailSetting = MailSettings.Create(account, password); // account di spedizione per la newsletter
                MailMessage Msg = new MailMessage();
                Msg.From = new MailAddress(mailSetting.MailSender, mailSetting.SenderDisplayName);

                Msg.To.Add(new MailAddress(account));

                foreach (string item in mailTo)
                    Msg.Bcc.Add(new MailAddress(item));

                Msg.Subject = mailTitle;
                Msg.Body = mailBody;
                Msg.IsBodyHtml = isBodyHtml;
                SmtpClient Smtp = this._setSmtpServer(mailSetting);
                Smtp.Send(Msg);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            
        }


        /// <summary>
        /// Divide una lista di contatti in una lista di liste di dimensione chunkSize
        /// </summary>
        /// <param name="list"></param>
        /// <param name="numberOfElementsPerList"></param>
        /// <returns></returns>
        public List<IEnumerable<string>> SplitEmailList(List<string> list, int chunkSize)
        {
            List<IEnumerable<string>> listOfLists = new List<IEnumerable<string>>();

            int index = 0;
            while (index < list.Count)
            {
                int count = list.Count - index > chunkSize ? chunkSize : list.Count - index;
                listOfLists.Add(list.GetRange(index, count));

                index += chunkSize;
            }
          
            return listOfLists;
        }

        //public void SendEmailWithGraphics(string mailTo, string mailTitle, string mailBody, string htmlPagePath, string cssPagePath, bool isBodyHtml)
        //{
        //    string emailText = string.Empty;
        //    string emailCss = string.Empty;
        //    string cssPlaceholder = System.Configuration.ConfigurationManager.AppSettings["MAIL_CSS_PLACEHOLDER"];
        //    string titlePlaceholder = System.Configuration.ConfigurationManager.AppSettings["MAIL_TITLE_PLACEHOLDER"];
        //    string bodyPlaceholder = System.Configuration.ConfigurationManager.AppSettings["MAIL_BODY_PLACEHOLDER"];
            
        //    try
        //    {
        //        emailText = @System.IO.File.ReadAllText(@htmlPagePath, System.Text.Encoding.UTF8);
        //        emailCss = @System.IO.File.ReadAllText(cssPagePath, System.Text.Encoding.UTF8);

        //        emailText = emailText.Replace(cssPlaceholder, emailCss);
        //        emailText = emailText.Replace(titlePlaceholder, mailTitle);
        //        emailText = emailText.Replace(bodyPlaceholder, mailBody);

        //        MailSettings mailSetting = MailSettings.Create();
        //        using (MailMessage Msg = new MailMessage())
        //        {
        //            Msg.From = new MailAddress(mailSetting.MailSender, mailSetting.SenderDisplayName);
        //            Msg.To.Add(new MailAddress(mailTo));
        //            Msg.Subject = mailTitle;
        //            Msg.Body = emailText;
        //            Msg.IsBodyHtml = isBodyHtml;

        //            #region EXTERNAL RESOURCES
        //            //if (path2typeResources != null)
        //            //{
        //            //    AlternateView avHtml = AlternateView.CreateAlternateViewFromString(emailText, null, System.Net.Mime.MediaTypeNames.Text.Html);
        //            //    // Alternative view for unsupported clients
        //            //    AlternateView avText = AlternateView.CreateAlternateViewFromString(mailBody, null, System.Net.Mime.MediaTypeNames.Text.Plain);

        //            //    List<LinkedResource> resources = new List<LinkedResource>();
        //            //    foreach (var item in path2typeResources)
        //            //    {
        //            //        System.Net.Mime.ContentType type = new System.Net.Mime.ContentType(item.Value); // "text/css"
        //            //        LinkedResource linkedResource = new LinkedResource(@item.Key, type);         // "../../css/style.css"   
        //            //        linkedResource.ContentId = "ID_CSS";
        //            //        resources.Add(linkedResource);
        //            //    }

        //            //    foreach (var item in resources)
        //            //    {
        //            //        avHtml.LinkedResources.Add(item);
        //            //    }

        //            //    Msg.AlternateViews.Add(avHtml);
        //            //    Msg.AlternateViews.Add(avText);
        //            //}
        //            #endregion

        //            SmtpClient Smtp = this._setSmtpServer(mailSetting);
        //            Smtp.Send(Msg);
        //        }

        //    }
        //    catch (Exception ex)
        //    {
        //        // throw;
        //    }            
        //}

        public void SendEmailWithGraphics(string mailTo, string mailTitle, string mailBody, string template, bool isBodyHtml)
        {
            string emailText = string.Empty;
            string emailCss = string.Empty;

            string titlePlaceholder = System.Configuration.ConfigurationManager.AppSettings["MAIL_TITLE_PLACEHOLDER"];
            string bodyPlaceholder = System.Configuration.ConfigurationManager.AppSettings["MAIL_BODY_PLACEHOLDER"];

            try
            {
                emailText = @System.IO.File.ReadAllText(template, System.Text.Encoding.UTF8);

                emailText = emailText.Replace(titlePlaceholder, mailTitle);
                emailText = emailText.Replace(bodyPlaceholder, mailBody);

                MailSettings mailSetting = MailSettings.Create();
                using (MailMessage Msg = new MailMessage())
                {
                    Msg.From = new MailAddress(mailSetting.MailSender, mailSetting.SenderDisplayName);
                    Msg.To.Add(new MailAddress(mailTo));
                    Msg.Subject = mailTitle;
                    //Msg.Body = emailText;
                    Msg.IsBodyHtml = isBodyHtml;

                    #region EXTERNAL RESOURCES
                    //if (path2typeResources != null)
                    //{
                        AlternateView avHtml = AlternateView.CreateAlternateViewFromString(emailText, null, System.Net.Mime.MediaTypeNames.Text.Html);
                        // Alternative view for unsupported clients
                        AlternateView avText = AlternateView.CreateAlternateViewFromString(mailBody, null, System.Net.Mime.MediaTypeNames.Text.Plain);

                        List<LinkedResource> resources = new List<LinkedResource>();

                        LinkedResource linkedResource1 = new LinkedResource(@"http://www.ateneolibri.it/Images/logoAL.png", MediaTypeNames.Image.Gif);//MediaTypeNames.Image.Gif);
                        //LinkedResource linkedResource2 = new LinkedResource(@"C:\TFSCodeplex\ateneolibri\AteneoLibri\css\style.css", "text/css");
                        linkedResource1.ContentId = "Main_IMG";
                        //linkedResource2.ContentId = "Main_CSS";
                        resources.Add(linkedResource1);
                        //resources.Add(linkedResource2);
                        //}

                        foreach (var item in resources)
                        {
                            avHtml.LinkedResources.Add(item);
                        }

                        Msg.AlternateViews.Add(avHtml);
                        Msg.AlternateViews.Add(avText);
                    //}
                    #endregion

                    SmtpClient Smtp = this._setSmtpServer(mailSetting);
                    Smtp.Send(Msg);
                }

            }
            catch (Exception ex)
            {
                // throw;
            }
        }
    }
}